package tt.dz.egobus.servicemanager.base.service;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.transform.ResultTransformer;
import org.springframework.transaction.annotation.Transactional;
import tt.dz.egobus.base.dao.BaseDao;
import tt.dz.egobus.base.entity.BaseEntity;
import tt.dz.egobus.base.service.AbstractBaseService;
import tt.dz.egobus.bean.Pagination;
import tt.dz.egobus.servicemanager.base.dao.ExtendDao;
import tt.dz.egobus.servicemanager.bean.PagingationStart;
import tt.dz.egobus.servicemanager.core.exception.BusinessException;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static tt.dz.egobus.servicemanager.bean.ServiceManagerCodeStatus.PARAM_ENTITY_ERROR;

/**
 * @author Anson
 * @date 17-3-14
 * @name 扩展Service
 * @since 1.0.1
 */
public abstract class AbstractExtendService<E extends BaseEntity, PK extends Serializable>
        extends AbstractBaseService<E, PK> implements ExtendBaseService<E, PK> {

    @Transactional
    @Override
    public E get(PK id) {
        return super.get(id);
    }

    @Transactional
    @Override
    public void save(E entity) {
        super.save(entity);
    }

    @Transactional
    @Override
    public void update(E entity) {
        super.update(entity);
    }

    @Transactional
    @Override
    public void delete(E entity) {
        super.delete(entity);
    }

    @Transactional
    @Override
    public void merge(E entity) {
        super.merge(entity);
    }

    @Transactional
    @Override
    public E findOne(String dsl, Map<String, Object> params) {
        return super.findOne(dsl, params);
    }

    @Transactional
    @Override
    public E findOne(DetachedCriteria detachedCriteria) {
        return super.findOne(detachedCriteria);
    }

    @Transactional
    @Override
    public List<?> list(String dsl, Map<String, Object> params, ResultTransformer resultTransformer) {
        return super.list(dsl, params, resultTransformer);
    }

    @Transactional
    @Override
    public List<?> list(DetachedCriteria detachedCriteria, ResultTransformer resultTransformer) {
        return super.list(detachedCriteria, resultTransformer);
    }

    @Transactional
    @Override
    public void batch(String named, Map<String, Object> params) {
        super.batch(named, params);
    }


    @Transactional
    @Override
    public void deletePK(PK pk) {
        E e = this.get(pk);
        if (e == null) {
            throw new BusinessException(PARAM_ENTITY_ERROR.getCodeStatus());
        }
        this.delete(e);
    }


    @Transactional
    @Override
    public List<E> list(Map<String, Object> params) {
        return this.list(params, null);
    }

    @Transactional
    @Override
    public List<E> list(Map<String, Object> params, List<String> orders) {
        ExtendDao<E, PK> dao = this.getExtendDao();
        return dao.list(params);
    }

    @Transactional
    @Override
    public int count(Map<String, Object> params) {
        ExtendDao<E, PK> dao = this.getExtendDao();
        return dao.count(params);
    }


    @Transactional
    @Override
    public Pagination<E> pagination(Map<String, Object> params, int currentPageNo, int maxResult) {
        return this.pagination(params, currentPageNo, maxResult, null);
    }

    @Transactional
    @Override
    public Pagination<E> pagination(Map<String, Object> params, int currentPageNo, int maxResult,
                                    List<String> orderPropertyList) {
        ExtendDao<E, PK> dao = this.getExtendDao();
        return dao.pagination(params, currentPageNo, maxResult, orderPropertyList);
    }

    @Transactional
    @Override
    public PagingationStart<E> paginationStart(Map<String, Object> params, int start, int maxResult) {
        ExtendDao<E, PK> dao = this.getExtendDao();
        return dao.paginationStart(params, start, maxResult, maxResult);
    }

    @Transactional
    @Override
    public PagingationStart<E> paginationStart(Map<String, Object> params, int start, int maxResult,
                                               List<String> orderPropertyList) {
        ExtendDao<E, PK> dao = this.getExtendDao();
        return dao.paginationStart(params, start, maxResult, orderPropertyList);
    }

    @Transactional
    @Override
    public List<E> queryByIds(PK[] ids) {
        if (null == ids || ids.length == 0) {
            throw new BusinessException(PARAM_ENTITY_ERROR.getCodeStatus());
        }
        ExtendDao<E, PK> dao = this.getExtendDao();
        return dao.queryByIds(ids);
    }

    @Override
    @Transactional
    public Date getCurrentDbDate() {
        //this.getExtendDao().getDbDate()
        return new Date();

    }

    /**
     * 获取扩展的dao
     *
     * @return
     * @throws IllegalArgumentException
     */
    protected ExtendDao<E, PK> getExtendDao() throws IllegalArgumentException {
        BaseDao dao = this.getSelfDao();
        if (dao == null) {
            throw new IllegalArgumentException("未能获取当前扩展的dao");
        }

        if (!ExtendDao.class.isAssignableFrom(dao.getClass())) {
            throw new IllegalArgumentException("未能获取当前扩展的dao");
        }
        return (ExtendDao<E, PK>) dao;
    }


}
